package net.xxcxcxcx.xc_enhancedmob.skills;

import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting;
import net.xxcxcxcx.xc_enhancedmob.config.CustomConfig;
import net.xxcxcxcx.xc_enhancedmob.config.skill.SkillConfig;
import net.xxcxcxcx.xc_enhancedmob.config.skill.SkillsConfig;
import net.xxcxcxcx.xc_enhancedmob.register.ConfigRegister;

import java.util.ArrayList;
import java.util.List;

import static net.xxcxcxcx.xc_enhancedmob.math.IntToRoman.intToRoman;

/**
 * 技能的基类包含了一些技能的默认设置，继承时候记得SkillHelper里面添加初始化+语言文件初始化
 */
public abstract class BaseSkill implements Skill {
    private List<Integer> LevelCost;
    private List<String> conflict = null;//互斥技能名称
    private Integer Maxlevel, Preparationtime, Cooldown, InsideCooldown, MaxUseCount, InsideMaxUseCount;
    private int Level, UseCount, InsideUesCount;
    private boolean WhetherPreparation = false;
    private long time;

    protected BaseSkill() {
    }

    protected BaseSkill(int level) {
        Level = level;
        SkillConfig skillConfig = getAConfig();
        if (skillConfig == null) return;
        Maxlevel = skillConfig.getMaxlevel();
        Preparationtime = skillConfig.getPreparationtime();
        Cooldown = skillConfig.getCooldown();
        InsideCooldown = skillConfig.getInsideCooldown();
        MaxUseCount = skillConfig.getMaxUseCount();
        InsideMaxUseCount = skillConfig.getInsideMaxUseCount();
        LevelCost = skillConfig.getLevelCost();
        conflict = skillConfig.getConflict();
    }

    protected BaseSkill(NbtCompound nbtCompound) {
        readbyNbtCompound(nbtCompound);
    }

    @Override
    public String getName() {
        return this.getClass().getSimpleName();
    }

    public int getEffectiveSequence() {
        return 0;
    }

    //获取技能等级
    public int getSkillLevel() {
        return Level;
    }

    //设置技能等级
    public void setSkillLevel(int i) {
        Level = i;
    }

    //获取技能使用时间
    public long getSkilltime() {
        return time;
    }

    //设置技能使用时间
    public void setSkilltime(long i) {
        time = i;
    }

    //获取技能使用次数
    public int getSkillUsecount() {
        return UseCount;
    }

    //设置技能使用次数
    public void setSkillUsecount(int i) {
        UseCount = i;
    }

    //获取技能内置使用次数
    public int getSkillInsideUsecount() {
        return InsideUesCount;
    }

    //设置技能内置使用次数
    public void setSkillInsideUsecount(int i) {
        InsideUesCount = i;
    }

    //获取技能最大等级
    public Integer getSkillMaxLevel() {
        return Maxlevel;
    }

    //设置技能最大等级
    public void setSkillMaxLevel(int i) {
        Maxlevel = i;
    }

    //获取技能准备时间
    public Integer getPreparationTime() {
        return Preparationtime;
    }

    //设置技能准备时间
    public void setPreparationTime(int i) {
        Preparationtime = i;
    }

    //获取技能是否准备
    public boolean getwhetherPreparationTime() {
        return WhetherPreparation;
    }

    //设置技能是否准备
    public void setwhetherPreparationTime(boolean i) {
        WhetherPreparation = i;
    }

    //获取技能冷却时间
    public Integer getCooldown() {
        return Cooldown;
    }

    //设置技能冷却时间
    public void setCooldown(int i) {
        Cooldown = i;
    }

    //获取技能内部冷却时间
    public Integer getInsideCooldown() {
        return InsideCooldown;
    }

    //设置技能内部冷却时间
    public void setInsideCooldown(int i) {
        InsideCooldown = i;
    }

    //获取技能最大使用次数
    public Integer getMaxUseCount() {
        return MaxUseCount;
    }

    //设置技能最大使用次数
    public void setMaxUseCount(int i) {
        MaxUseCount = i;
    }

    //获取技能内部最大使用次数
    public Integer getInsideMaxUseCount() {
        return InsideMaxUseCount;
    }

    //设置技能内部最大使用次数
    public void setInsideMaxUseCount(int i) {
        InsideMaxUseCount = i;
    }

    public NbtCompound getNbtCompound() {
        NbtCompound nbtCompound = new NbtCompound();
        nbtCompound.putBoolean("WhetherPreparation", WhetherPreparation);
        nbtCompound.putInt("Level", Level);
        nbtCompound.putLong("time", time);
        nbtCompound.putInt("UseCount", UseCount);
        nbtCompound.putInt("InsideUesCount", InsideUesCount);
        return nbtCompound;
    }

    //通过nbt新建
    public void readbyNbtCompound(NbtCompound nbtCompound) {
        WhetherPreparation = nbtCompound.getBoolean("WhetherPreparation");
        Level = nbtCompound.getInt("Level");
        time = nbtCompound.getLong("time");
        UseCount = nbtCompound.getInt("UseCount");
        InsideUesCount = nbtCompound.getInt("InsideUesCount");
        SkillConfig skillConfig = getAConfig();
        if (skillConfig == null) return;
        Maxlevel = skillConfig.getMaxlevel();
        Preparationtime = skillConfig.getPreparationtime();
        Cooldown = skillConfig.getCooldown();
        InsideCooldown = skillConfig.getInsideCooldown();
        MaxUseCount = skillConfig.getMaxUseCount();
        InsideMaxUseCount = skillConfig.getInsideMaxUseCount();
        LevelCost = skillConfig.getLevelCost();
        conflict = skillConfig.getConflict();
    }

    @Override
    public Text getText() {
        LiteralText literalText = new LiteralText("");
        TranslatableText text = new TranslatableText("skill." + getSkillRarity() + "." + getName());
        switch (getSkillRarity()) {
            case Common -> text.formatted(Formatting.WHITE);
            case Rare -> text.formatted(Formatting.BLUE);
            case Mystery -> text.formatted(Formatting.DARK_PURPLE);
            case BreakOut -> text.formatted(Formatting.DARK_GREEN);
            case DoubleEdged -> text.formatted(Formatting.YELLOW);
            case Legend -> text.formatted(Formatting.GOLD).formatted(Formatting.BOLD);
            case Demigod -> text.formatted(Formatting.RED).formatted(Formatting.BOLD);
            case Divine -> text.formatted(Formatting.GOLD).formatted(Formatting.BOLD).formatted(Formatting.OBFUSCATED);
            case Pollution -> text.formatted(Formatting.DARK_AQUA).formatted(Formatting.BOLD);
        }
        literalText.append(text);
        text = new TranslatableText(intToRoman(getSkillLevel()));
        switch (getSkillRarity()) {
            case Common -> text.formatted(Formatting.WHITE);
            case Rare -> text.formatted(Formatting.BLUE);
            case Mystery -> text.formatted(Formatting.DARK_PURPLE);
            case BreakOut -> text.formatted(Formatting.DARK_GREEN);
            case DoubleEdged -> text.formatted(Formatting.YELLOW);
            case Legend -> text.formatted(Formatting.GOLD).formatted(Formatting.BOLD);
            case Demigod -> text.formatted(Formatting.RED).formatted(Formatting.BOLD);
            case Divine -> text.formatted(Formatting.GOLD).formatted(Formatting.BOLD).formatted(Formatting.OBFUSCATED);
            case Pollution -> text.formatted(Formatting.DARK_AQUA).formatted(Formatting.BOLD);
        }
        literalText.append(text);
        return literalText;
    }

    @Override
    public SkillConfig getAConfig() {
        CustomConfig config = ConfigRegister.getConfig("SkillsConfig");
        if (config instanceof SkillsConfig skillsConfig) {
            return skillsConfig.getConfig(getName());
        }
        return null;
    }

    @Override
    public SkillConfig getDefaultConfig() {
        List<Integer> list = new ArrayList<>();
        List<String> Strings = new ArrayList<>();
        return new SkillConfig(getName(), null, null, null, null,
                null, null, list, Strings, getConfigMessage(null), getSkillRarity());
    }

    @Override
    public String getConfigMessage(SkillConfig skillConfig) {
        return "这是一段默认的技能描述文本";
    }

    @Override
    public SkillRarity getSkillRarity() {
        return SkillRarity.Common;
    }

    @Override
    public int getSkillLevelCost() {
        if (getLevelCost() == null || getLevelCost().isEmpty()) return 1;
        if (Level >= getLevelCost().size()) return getLevelCost().get(getLevelCost().size() - 1);
        return getLevelCost().get(Level);
    }


    @Override
    public boolean canUseAbility(MobEntity mobEntity) {
        return true;
    }

    @Override
    public boolean onAttribute(MobEntity mobEntity) {
        return Skill.super.onAttribute(mobEntity);
    }

    @Override
    public boolean onAbilityUse(MobEntity mobEntity) {
        return Skill.super.onAbilityUse(mobEntity);
    }

    @Override
    public boolean passiveApply(MobEntity mobEntity) {
        return Skill.super.passiveApply(mobEntity);
    }

    @Override
    public boolean onTreat(MobEntity mobEntity, Ref<Float> amount) {
        return Skill.super.onTreat(mobEntity, amount);
    }

    @Override
    public boolean onStartAttack(MobEntity attacker, LivingEntity entity) {
        return Skill.super.onStartAttack(attacker, entity);
    }

    @Override
    public boolean onDamaged(LivingEntity attacker, MobEntity target, DamageSource source, Ref<Float> amount, boolean ismob, boolean remote) {
        return Skill.super.onDamaged(attacker, target, source, amount, ismob, remote);
    }

    @Override
    public boolean onAttack(MobEntity attacker, LivingEntity target, DamageSource source, Ref<Float> amount, boolean ismob, boolean remote) {
        return Skill.super.onAttack(attacker, target, source, amount, ismob, remote);
    }

    @Override
    public boolean onDeath(LivingEntity attacker, MobEntity target, DamageSource source, boolean ismob, boolean remote) {
        return Skill.super.onDeath(attacker, target, source, ismob, remote);
    }

    @Override
    public List<Integer> getLevelCost() {
        return LevelCost;
    }

    @Override
    public void setLevelCost(List<Integer> levelCost) {
        LevelCost = levelCost;
    }

    @Override
    public List<String> getConflict() {
        return conflict;
    }

    @Override
    public void setConflict(List<String> conflict) {
        this.conflict = conflict;
    }
}
